/**
 * JAVACC DEMO 1.0
 * @copy right apache company All rights reserved. 
 * @Package com.apache.rpc.server.impl  
 */
package com.apache.rpc.client.protocol;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Map;

import com.apache.api.vo.ResultEntity;
import com.apache.rpc.util.JsonEntityParese;
import com.apache.tools.ConfigUtil;
import com.apache.tools.StrUtil;

/**
 * description:  socket通信接口实现
 * @author Hou Dayu 创建时间：2014-10-28  
 * @Copyright(c)2014:
 */
public class SocketProtocolServiceClient extends AbstractProtocolClient {

	public ResultEntity doService(String beanId, String methodKey, Map<String, Object> params) {
		ResultEntity resultEntity = null;
		Socket server = null;
		if (null == register) {
			resultEntity = getResultEntity("没有发布待执行的接口信息");
			return resultEntity;
		}
		String httpIp = register.getAddress();
		String httpProt = register.getPort();
		if ("".equals(httpProt) || null == httpProt)
			httpProt = "9001";
		try {
			String xmlParams = this.buildXml(beanId, methodKey, "socket", params);
			server = new Socket();
			SocketAddress remoteAddr = new InetSocketAddress(httpIp, Integer.parseInt(httpProt));
			server.connect(remoteAddr, 30000); //等待建立连接的超时时间为30秒
			server.setSoTimeout(Integer.parseInt(StrUtil.doNull(
					ConfigUtil.getInstance().getValueByKey("socketTimeOut"), "100")));//毫秒
			String temp = doSocket(server, xmlParams);
			if ("".equals(temp) || null == temp) {
				resultEntity = getResultEntity("接口调用超时");
				return resultEntity;
			}
			resultEntity = JsonEntityParese.instance().toBean(temp, ResultEntity.class);
		} catch (Exception e1) {
			resultEntity = getResultEntity(e1.getMessage());
		} finally {
			try {
				if (null != server)
					server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resultEntity;
	}

	private String doSocket(Socket socket, String params) throws IOException {
		String temp = "";
		socket.getOutputStream().write(params.getBytes("UTF-8"));
		socket.getOutputStream().flush();
		StringBuffer rtnMsgc = new StringBuffer();

		byte[] bs_Length = new byte[4];//数据内容长度
		int readLength = socket.getInputStream().read(bs_Length, 0, 4);//报文长度
		int dataLength = 0;
		if (readLength > 0) {
			dataLength = bytesToInt(bs_Length);
		}
		if (dataLength < 1)
			return temp;

		BufferedReader rd;
		rd = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
		String str;
		while ((str = rd.readLine()) != null) {
			rtnMsgc.append(str + "\n");
		}
		temp = rtnMsgc.toString();
		return temp;
	}

	/**
	 * description:  将字节数组转成int
	 * @param n
	 * @return   
	 */
	private int bytesToInt(byte[] bytes) {
		int number = bytes[0] & 0xFF;
		// "|="按位或赋值。  
		number |= ((bytes[1] << 8) & 0xFF00);
		number |= ((bytes[2] << 16) & 0xFF0000);
		number |= ((bytes[3] << 24) & 0xFF000000);
		return number;
	}

}
